import util from '@/js/util/util.js';
import array from '@/js/util/array.js';

let store = {
    state: {
        canvas: {// 画板参数
            layout: '1',// 1: 固定布局; 2: 固定布局自适应窗口; 3: 布局自适应窗口
            width: 1920,
            height: 1080,
            scale: 100,
            name: '',
            icon: ''
        },
        pageList: [
            {
                name: '页面1',
                visible: true
            }
        ],
        pageIndex: 0,
        elementList: [],// 所有组件集合
        elementSortList: [],// 用于排序所有组件集合
        currentElementList: [],// 选中组件集合
    },
    elementMap: {},
    elementFlagMap: {},
    initialize: function() {
        let state = {
            canvas: {
                layout: '1',
                width: 1920,
                height: 1080,
                scale: 100,
                name: '',
                icon: ''
            },
            pageList: [
                {
                    name: '页面1',
                    visible: true
                }
            ],
            pageIndex: 0,
            elementList: []
        };
        this.set(state);
    },
    set: function(state) {
        state = util.clone(state);
        this.state.canvas.layout = state.canvas.layout;
        this.state.canvas.width = state.canvas.width;
        this.state.canvas.height = state.canvas.height;
        this.state.canvas.name = state.canvas.name;
        this.state.canvas.icon = state.canvas.icon;
        this.state.pageIndex = state.pageIndex;
        this.setPageList(state.pageList);
        this.setElementList(state.elementList);
    },
    clone: function() {
        let state = {};
        state.canvas = {
            layout: this.state.canvas.layout,
            width: this.state.canvas.width,
            height: this.state.canvas.height,
            name: this.state.canvas.name,
            icon: this.state.canvas.icon
        };
        state.pageIndex = this.state.pageIndex;
        state.pageList = util.clone(this.state.pageList);
        state.elementList = util.clone(this.state.elementSortList).reverse();
        return state;
    },
    getCanvas: function() {
        return this.state.canvas;
    },
    getScale: function() {
        return this.state.canvas.scale / 100;
    },
    setCanvas: function(canvas) {
        if (canvas) {
            if (canvas.layout) {
                this.state.canvas.layout = canvas.layout;
            }
            if (canvas.width) {
                this.state.canvas.width = canvas.width;
            }
            if (canvas.height) {
                this.state.canvas.height = canvas.height;
            }
            if (canvas.scale) {
                this.state.canvas.scale = canvas.scale;
            }
            if (canvas.name) {
                this.state.canvas.name = canvas.name;
            }
            if (canvas.icon || canvas.icon === '') {
                this.state.canvas.icon = canvas.icon;
            }
        }
    },
    getEditor: function() {
        let editor = document.getElementById(window.getRootName() + 'EDITOR');
        return editor;
    },
    getElementList: function() {
        return this.state.elementList;
    },
    getElementMap: function() {
        return this.elementMap;
    },
    getElementById: function(id) {
        return this.elementMap[id];
    },
    getChildrenElementListById: function(element) {
        let childrenElementList = [];
        for (let index = 0; index < element.attribute.children.length; index++) {
            const item = element.attribute.children[index];
            if (this.elementMap[item.id]) {
                childrenElementList.splice(index, 0, this.elementMap[item.id]);
            }
        }
        return childrenElementList;
    },
    getElementFlagMap: function() {
        return this.elementFlagMap;  
    },
    getElementFlagMapById: function(id) {
        return this.elementFlagMap[id];  
    },
    setElementFlagMapById: function(id, flag) {
        if (id) {
            this.elementFlagMap[id] = flag;
        }
        return this;
    },
    resetElementFlagMap: function() {
        for (const key in this.elementFlagMap) {
            if (Object.hasOwnProperty.call(this.elementFlagMap, key)) {
                this.elementFlagMap[key] = true;
            }
        }
    },
    setElementList: function(array) {
        this.elementMap = {};
        this.elementFlagMap = {};
        let elementMap = {};
        for (let i = this.state.elementList.length - 1; i >= 0; i --) {
            elementMap[this.state.elementList[i].id] = this.state.elementList[i];
            this.state.elementList.splice(i, 1);
        }
        for (let i = this.state.elementSortList.length - 1; i >= 0; i --) {
            this.state.elementSortList.splice(i, 1);
        }
        for (let i = this.state.currentElementList.length - 1; i >= 0; i --) {
            this.state.currentElementList.splice(i, 1);
        }
        if (array) {
            for (let i = 0; i < array.length; i++) {
                let element = elementMap[array[i].id];
                if (element) {
                    for (let j in array[i]) {
                        element[j] = util.clone(array[i][j]);
                    }
                } else {
                    element = array[i];
                    if (element.component === 'Group') {
                        for (let index = 0; index < element.attribute.children.length; index++) {
                            const item = element.attribute.children[index];
                            this.elementMap[item.id] = item;
                            this.elementFlagMap[item.id] = true;
                        }
                        this.elementMap[element.id] = element;
                        this.elementFlagMap[element.id] = true;
                    } else {
                        this.elementMap[element.id] = element;
                        this.elementFlagMap[element.id] = true;
                    }
                }
                this.state.elementList.splice(i, 0, element);
                this.state.elementSortList.splice(0, 0, element);
            }
        }
        return this;
    },
    getElementIndex: function(element) {
        // let index = -1;
        // if (element.data.pid) {
        //     let parentElement = this.getElementById(element.data.pid);
        //     index = parentElement.children.indexOf(element);
        // } else {
        //     index = this.state.elementList.indexOf(element);
        // }
        // return index;
        return this.state.elementList.indexOf(element);
    },
    addElement: function(element) {
        element.attribute.page = this.state.pageIndex;
        element.style['z-index'] = this.state.elementList.length + 11;
        this.state.elementList.splice(this.state.elementList.length, 0, element);
        this.state.elementSortList.splice(0, 0, element);
        if (element.component === 'Group') {
            for (let index = 0; index < element.attribute.children.length; index++) {
                const item = element.attribute.children[index];
                this.elementMap[item.id] = item;
                this.elementFlagMap[item.id] = true;
            }
            this.elementMap[element.id] = element;
            this.elementFlagMap[element.id] = true;
        } else {
            this.elementMap[element.id] = element;
            this.elementFlagMap[element.id] = true;
        }
        return this;
    },
    addTempleteElement: function(template) {
        let pageLength = this.state.pageList.length;
        for (let i = 0; i < this.state.elementList.length; i++) {
            const element = this.state.elementList[i];
            element.style['z-index'] = template.elementList.length + 1;
        }
        this.resetTempleteByPage(template);
        for (let index = 0; index < template.elementList.length; index++) {
            const element = template.elementList[index];
            element.attribute.page = +element.attribute.page + pageLength;
            this.state.elementList.splice(this.state.elementList.length, 0, element);
            this.state.elementSortList.splice(this.state.elementList.length, 0, element);
            if (element.component === 'Group') {
                for (let index = 0; index < element.attribute.children.length; index++) {
                    const item = element.attribute.children[index];
                    this.elementMap[item.id] = item;
                    this.elementFlagMap[item.id] = true;
                }
                this.elementMap[element.id] = element;
                this.elementFlagMap[element.id] = true;
            } else {
                this.elementMap[element.id] = element;
                this.elementFlagMap[element.id] = true;
            }
        }
    },
    resetTempleteByPage: function(template) {
        let pageLength = this.state.pageList.length;
        for (let i = 0; i < template.elementList.length; i ++) {
            let eventList = template.elementList[i].event;
            for (let j = eventList.length - 1; j >= 0; j --) {
                if (eventList[j].param && Array.isArray(eventList[j].param)) {
                    let list = eventList[j].param;
                    for (let h = list.length - 1; h >= 0; h --) {
                        list[h] = list[h] + pageLength;
                    }
                }
            }
            if (template.elementList[i].component === 'Group') {
                this.resetTempleteByPage(template);
            }
        }
    },
    removeElement: function(element) {
        let index = this.state.elementList.indexOf(element);
        if (index >= 0) {
            this.state.elementList.splice(this.state.elementList.indexOf(element), 1);
            this.state.elementSortList.splice(this.state.elementSortList.indexOf(element), 1);
            this.removeRelateByElementList([element]);
            if (element.component === 'Group') {
                for (let index = 0; index < element.attribute.children.length; index++) {
                    const item = element.attribute.children[index];
                    if (this.elementMap[item.id]) {
                        delete this.elementMap[item.id]
                    }
                }
                delete this.elementMap[element.id]
            } else {
                if (this.elementMap[element.id]) {
                    delete this.elementMap[element.id]
                }
            }
            return true;
        } else {
            return false;
        }
    },
    removeElementByPageIndex: function(index) {
        let elementList = [];
        for (let i = this.state.elementList.length - 1; i >= 0; i --) {
            if (this.state.elementList[i].attribute.page == index) {
                elementList.push(this.state.elementList[i]);
                this.state.elementList.splice(i, 1);
            }
        }
        for (let i = this.state.elementSortList.length - 1; i >= 0; i --) {
            if (this.state.elementSortList[i].attribute.page == index) {
                this.state.elementSortList.splice(i, 1);
            }
        }
        this.removeRelateByElementList(elementList);
        return true;
    },
    batchRemoveElement: function(elementList) {
        let success = false;
        for (let i = 0; i < elementList.length; i ++) {
            let removeSuccess = this.removeElement(elementList[i]);
            success = success || removeSuccess;
        }
        return success;
    },
    getCurrentElementList: function() {
        return this.state.currentElementList;
    },
    setCurrentElementList: function(array) {
        for (let i = this.state.currentElementList.length - 1; i >= 0; i --) {
            this.state.currentElementList.splice(i, 1);
        }
        if (array) {
            for (let i = 0; i < array.length; i ++) {
                this.state.currentElementList.splice(i, 0, array[i]);
            }
        }
        return this;
    },
    removeCurrentElementAt: function(index) {
        if (index >= 0 && index < this.state.currentElementList.length) {
            this.state.currentElementList.splice(index, 1);
            return true;
        } else {
            return false;
        }
    },
    removeCurrentElement: function(element) {
        let index = this.state.currentElementList.indexOf(element);
        return this.removeCurrentElementAt(index);
    },
    moveElementSort: function(from, to) {
        if (from >= 0 && from < this.state.elementSortList.length && to >= 0 && to < this.state.elementSortList.length && from != to) {
            let element = this.state.elementSortList[from];
            this.state.elementSortList.splice(from, 1);
            this.state.elementSortList.splice(to, 0, element);
        }
        return this;
    },
    addCurrentElement: function(element) {
        this.state.currentElementList.splice(this.state.currentElementList.length, 0, element);
        return this;
    },
    getElementSortList: function() {
        return this.state.elementSortList;
    },
    getElementSortIndex: function(element) {
        return this.state.elementSortList.indexOf(element);
    },
    sortElementList: function() {
        for (let i = 0; i < this.state.elementSortList.length; i ++) {
            this.state.elementSortList[i].style['z-index'] = (this.state.elementSortList.length - i + 10);
        }
    },
    setPageIndex: function(index) {
        this.state.pageIndex = index;
        return this;
    },
    getPageIndex: function() {
        return this.state.pageIndex;
    },
    setPageList: function(array) {
        for (let i = this.state.pageList.length - 1; i >= 0; i --) {
            this.state.pageList.splice(i, 1);
        }
        if (array) {
            for (let i = 0; i < array.length; i ++) {
                this.state.pageList.splice(i, 0, array[i]);
            }
        }
        return this;
    },
    removePageAt: function(index) {
        if (this.state.pageList.length > 1 && index >= 0 && index < this.state.pageList.length) {
            this.removeElementByPageIndex(index);
            this.state.pageList.splice(index, 1);
            for (let i = 0; i < this.state.elementList.length; i ++) {
                let element = this.state.elementList[i];
                if (element.attribute.page > index) {
                    element.attribute.page --;
                }
            }
            this.removeRelateByPage(index);
            return true;
        } else {
            return false;
        }
    },
    getPageList: function() {
        return this.state.pageList;
    },
    addPage: function(page) {
        this.state.pageList.splice(this.state.pageList.length, 0, page);
        return this;
    },
    copyPage: function(index) {
        for (let i = 0; i < this.state.elementList.length; i ++) {
            let item = this.state.elementList[i];
            if (item.attribute.page === index) {
                let element = util.clone(item);
                element.id = util.getID();
                this.addElement(util.clone(element));
            }
        }
        return this;
    },
    addAnimate: function(element, animate) {
        element.animate.splice(element.animate.length, 0, animate);
        return element;
    },
    removeAnimate: function(element, animate) {
        let index = element.animate.indexOf(animate);
        this.removeAnimateAt(element, index);
        return element;
    },
    removeAnimateAt: function(element, index) {
        if (index >= 0 && index < element.animate.length) {
            element.animate.splice(index, 1);
        }
        return element;
    },
    addEvent: function(element, event) {
        element.event.splice(element.event.length, 0, event);
        return element;
    },
    removeEvent: function(element, event) {
        let index = element.event.indexOf(event);
        this.removeEventAt(element, index);
        return element;
    },
    removeEventAt: function(element, index) {
        if (index >= 0 && index < element.event.length) {
            element.event.splice(index, 1);
        }
        return element;
    },
    removeRelateByElementList: function(elementList) {
        let elementIDObject = {};
        for (let i = 0; i < elementList.length; i ++) {
            elementIDObject[elementList[i].id] = 1;
        }
        for (let i = 0; i < this.state.elementList.length; i ++) {
            let eventList = this.state.elementList[i].event;
            for (let j = eventList.length - 1; j >= 0; j --) {
                if (eventList[j].param && eventList[j].param.elementID && elementIDObject[eventList[j].param.elementID]) {
                    eventList.splice(j, 1);
                }
            }
        }
    },
    removeRelateByPage: function(page) {
        for (let i = 0; i < this.state.elementList.length; i ++) {
            let eventList = this.state.elementList[i].event;
            for (let j = eventList.length - 1; j >= 0; j --) {
                if (eventList[j].param && Array.isArray(eventList[j].param)) {
                    let list = eventList[j].param;
                    for (let h = list.length - 1; h >= 0; h --) {
                        if (page == list[h]) {
                            list.splice(h, 1);
                        } else if (list[h] > page) {
                            list[h] --;
                        }
                    }
                }
            }
        }
    }
};

export default store;